bl_info = {
    "name": "视图层过滤器",
    "blender": (2, 80, 0),
    "category": "3D View",
    "author": "ok123.shop",        # 作者名称
    "version": (0, 0, 1),                # 插件版本号
    "location": "lq插件合集",                # 位置信息
    "description": "帮助你快速筛选视图层中是否隐藏、是否禁止渲染的对象",                # 插件描述
    "doc_url": "https://ok123.shop",        # 插件文档链接
    "tracker_url": "https://www.aleshu.com/creatorscenter/groupdetail/?groupid=8bb1b4434b38fb2fc91d3ee789af1cee",        # 报告问题链接
}


import bpy
import time
import threading

# 定义两个布尔型属性
def register_props():
    bpy.types.Scene.my_object_info = bpy.props.StringProperty(
        name="Object Info",
        description="Info of objects in the scene",
        default=""
    )
    bpy.types.Scene.checkbox_a = bpy.props.BoolProperty(name="A",default=True)
    bpy.types.Scene.checkbox_b = bpy.props.BoolProperty(name="B",default=False)

def unregister_props():
    del bpy.types.Scene.my_object_info
    del bpy.types.Scene.checkbox_a
    del bpy.types.Scene.checkbox_b

class HelloWorldPanel(bpy.types.Panel):
    """创建一个在3D视图侧边栏中显示的面板"""
    bl_label = "视图层过滤器"
    bl_idname = "VIEW3D_PT_hello_world"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "视图层过滤器"

    def draw(self, context):
        layout = self.layout
        scene = context.scene

        # 绘制复选框
        layout.prop(scene, "checkbox_a", text="已在视图层隐藏")
        layout.prop(scene, "checkbox_b", text="已在渲染中禁用")
        layout.operator("wm.hello_world_operator")
        layout.separator()

        if len(scene['matching_objects']) == 0:
            layout.label(text="很遗憾，没有查询到任何对象")
            return

        # 分割线
        layout.label(text="太棒了，一共查询到" + str(len(scene['matching_objects'])) + "个对象")
        layout.label(text="快捷操作:")
        buttonRow1 = layout.row()
        buttonRow2 = layout.row()
        # 在这一行上添加按钮
        buttonRow1.operator("object.id_for_button1", text="全部隐藏")
        buttonRow1.operator("object.id_for_button2", text="全部禁止渲染")
        buttonRow2.operator("object.id_for_button3", text="全部展示")
        buttonRow2.operator("object.id_for_button4", text="全部启用渲染")
        layout.separator()

        # 检查场景属性中是否有符合条件的对象名称列表
        if 'matching_objects' in scene:
            layout.label(text="对象详细信息:")

            for item in scene['matching_objects']:
                obj_name = item.name
                row = layout.row()
                row.label(text=obj_name + " ")


                # 视图隐藏快捷按钮
                view_icon = "HIDE_OFF" if not item.hide_get() else 'HIDE_ON'
                view_op = row.operator("object.change_view", text="", icon=view_icon)
                view_op.obj_name = obj_name;

                # 禁止渲染快捷按钮
                render_icon = "RESTRICT_RENDER_OFF" if not item.hide_render else 'RESTRICT_RENDER_ON'
                render_op = row.operator("object.change_render", text="", icon=render_icon)
                render_op.obj_name = obj_name;

                # 添加一个按钮，点击时复制对象名称
                copy_op = row.operator("object.copy_name_to_clipboard", text="", icon="CHECKMARK")
                copy_op.obj_name = obj_name


# 全部隐藏
class OBJECT_OT_id_for_button1(bpy.types.Operator):
    """点击后会针对当前筛选出来的所有对象进行全部隐藏视图"""
    bl_idname = "object.id_for_button1"
    bl_label = "全部隐藏视图"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        scene = context.scene
        if 'matching_objects' in scene:
            for item in scene['matching_objects']:
                item.hide_set(True)
        return {'FINISHED'}

# 全部显示
class OBJECT_OT_id_for_button3(bpy.types.Operator):
    """点击后会针对当前筛选出来的所有对象进行全部显示视图"""
    bl_idname = "object.id_for_button3"
    bl_label = "全部显示视图"
    bl_options = {'REGISTER', 'UNDO'}


    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        scene = context.scene
        if 'matching_objects' in scene:
            for item in scene['matching_objects']:
                item.hide_set(False)
        return {'FINISHED'}

# 全部禁止渲染
class OBJECT_OT_id_for_button2(bpy.types.Operator):
    """点击后会针对当前筛选出来的所有对象进行全部禁止渲染"""
    bl_idname = "object.id_for_button2"
    bl_label = "全部禁止渲染"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        scene = context.scene
        if 'matching_objects' in scene:
            for item in scene['matching_objects']:
                item.hide_render = True
        return {'FINISHED'}



# 全部允许渲染
class OBJECT_OT_id_for_button4(bpy.types.Operator):
    """点击后会针对当前筛选出来的所有对象进行全部允许渲染"""
    bl_idname = "object.id_for_button4"
    bl_label = "全部允许渲染"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        scene = context.scene
        if 'matching_objects' in scene:
            for item in scene['matching_objects']:
                item.hide_render = False
        return {'FINISHED'}













class OBJECT_OT_change_render(bpy.types.Operator):
    """点击后会快速变更当前对象的渲染启用/禁用"""
    bl_idname = "object.change_render"
    bl_label = "启用/禁用渲染"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        obj = context.scene.objects.get(self.obj_name)
        if obj:
            obj.hide_render = not obj.hide_render
        return {'FINISHED'}


class OBJECT_OT_change_view(bpy.types.Operator):
    """点击后会快速变更当前对象的视图显示/隐藏"""
    bl_idname = "object.change_view"
    bl_label = "开启/隐藏视图"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        obj = context.scene.objects.get(self.obj_name)
        if obj:
            obj.hide_set(not obj.hide_get())
        return {'FINISHED'}



class OBJECT_OT_copy_name_to_clipboard(bpy.types.Operator):
    """点击后会快速选中当前对象"""
    bl_idname = "object.copy_name_to_clipboard"
    bl_label = "选择对象"
    bl_options = {'REGISTER', 'UNDO'}

    obj_name: bpy.props.StringProperty()

    def execute(self, context):
        obj = context.scene.objects.get(self.obj_name)
        if obj:
            scene = context.scene
            for item in scene.objects:
                item.select_set(False)

            orgHide = obj.hide_get()
            obj.hide_set(False)
            obj.select_set(True)
            context.view_layer.objects.active = obj

            threading.Thread(target=self.restore_hide_state, args=(obj, orgHide)).start()
        return {'FINISHED'}

    def restore_hide_state(self, obj, orgHide):
        """Restore the original hide state of the object after a delay"""
        time.sleep(0.05)
        obj.hide_set(orgHide)
        #bpy.app.timers.register(functools.partial(self.set_hide_state, obj, orgHide))


class HelloWorldOperator(bpy.types.Operator):
    """点击按钮后，会立即开始过滤符合当前筛选项的所有对象，并罗列出来"""
    bl_idname = "wm.hello_world_operator"
    bl_label = "开始过滤"

    def execute(self, context):
        scene = context.scene
        viewSelect = scene.checkbox_a
        renderSelect = scene.checkbox_b

        objects_count = len(scene.objects)
        self.report({'INFO'}, str(objects_count))
        #info_messages = []
        matching_objects_names = []

        for obj in scene.objects:

            #obj.select_set(False)
            # 获取对象是否在视图中隐藏
            is_hidden_in_view = obj.hide_get()
            # 获取对象是否在渲染中隐藏
            is_hidden_in_render = obj.hide_render

            add = (viewSelect == is_hidden_in_view) and (renderSelect == is_hidden_in_render)
            if add:
                matching_objects_names.append(obj)

                #info_messages.append(f"{obj.name}")
                #obj.select_set(True)

        # 将对象信息更新到自定义场景属性中
        #scene.my_object_info = "\n".join(info_messages)
        scene['matching_objects'] = matching_objects_names

        self.report({'INFO'}, "Objects listed in the console.")

        return {'FINISHED'}

def register():
    register_props()
    bpy.utils.register_class(HelloWorldPanel)
    bpy.utils.register_class(HelloWorldOperator)
    bpy.utils.register_class(OBJECT_OT_copy_name_to_clipboard)
    bpy.utils.register_class(OBJECT_OT_change_view)
    bpy.utils.register_class(OBJECT_OT_change_render)
    bpy.utils.register_class(OBJECT_OT_id_for_button1)
    bpy.utils.register_class(OBJECT_OT_id_for_button2)
    bpy.utils.register_class(OBJECT_OT_id_for_button3)
    bpy.utils.register_class(OBJECT_OT_id_for_button4)

def unregister():
    unregister_props()
    bpy.utils.unregister_class(HelloWorldPanel)
    bpy.utils.unregister_class(HelloWorldOperator)
    bpy.utils.unregister_class(OBJECT_OT_copy_name_to_clipboard)
    bpy.utils.unregister_class(OBJECT_OT_change_view)
    bpy.utils.unregister_class(OBJECT_OT_change_render)
    bpy.utils.unregister_class(OBJECT_OT_id_for_button1)
    bpy.utils.unregister_class(OBJECT_OT_id_for_button2)
    bpy.utils.unregister_class(OBJECT_OT_id_for_button3)
    bpy.utils.unregister_class(OBJECT_OT_id_for_button4)

if __name__ == "__main__":
    register()